#ifndef A8_INIFILE_H
#define A8_INIFILE_H

#include <map>
#include <string>
#include <string.h>
#include <a8/xvalue.hpp>
#include <a8/strutils.hpp>
#include <a8/stringlist.hpp>

namespace a8
{
	class IniFile
	{
	public:
		IniFile(const std::string fileName) 
		{ 
			mFileName = fileName; 
		}

		virtual ~IniFile()
		{
		}

		std::string FileName() { return mFileName; }

		bool Load()
		{
			mSections.clear();

			std::string lineStr, tmpStr, sectionStr;
			a8::StringList tmpList;
			if(tmpList.LoadFromFile(mFileName.c_str())){
				for(int i = 0; i < tmpList.Count(); i++){
					lineStr = a8::getvalidstr(tmpList.String(i), tmpStr);
					//read section name
					if(tmpStr.size() >= 3 && 
					   tmpStr[0] == '[' && tmpStr[tmpStr.size() - 1] == ']'){
						sectionStr = tmpStr.substr(1, tmpStr.length() - 2);
						std::map<std::string, std::map<std::string, std::string> >::iterator itr = mSections.find(std::string(sectionStr));
						if(itr == mSections.end()){
							mSections[sectionStr] = std::map<std::string, std::string>();
						}
					}else if(sectionStr.size() > 0 && tmpStr.find('=') != std::string::npos){
						//read keyvalue
						int iPos = tmpStr.find('=');
						if(iPos != std::string::npos){
							std::map<std::string, std::map<std::string, std::string> >::iterator itr = mSections.find(std::string(sectionStr));
							if(itr != mSections.end()){
								std::string key = std::string(tmpStr, 0, iPos);
								std::string val = std::string(tmpStr, iPos + 1, tmpStr.length() - iPos - 1);
								itr->second[key] = val;
							}
						}
					}
				}//end for
				return true;
			}//end if
			return false;
		}

		template<typename T>
		a8::XValue ReadValue(const char* section, const char* key, const T& defval)
		{
			std::map<std::string, std::map<std::string, std::string> >::iterator itr = mSections.find(std::string(section));
			if(itr != mSections.end()){
				std::map<std::string, std::string>::iterator key_itr = itr->second.find(std::string(key));
				if(key_itr != itr->second.end()){
					return a8::XValue(key_itr->second);
				}
			}
			return a8::XValue(defval);
		}

	private:
		std::string mFileName;
		std::map<std::string, std::map<std::string, std::string> > mSections;
	};

}

#endif
